package cn.view;

import cn.algorithm.AlphaBetaAI;
import cn.controller.GameAction;
import cn.controller.MoveList;
import cn.controller.PlayerObject;
import cn.controller.PlayingEntity;

import javax.swing.*;
import java.awt.*;

public class Main extends JFrame {

    public static final int DEFAULT_SIDE = 11;

    public static JPanel panel;
    public final AnyShapeButton[][] gamePiece;

    public final int gridSize;
    public final boolean swap;
    public int moveNumber;
    public MoveList moveList;

    public int currentPlayer;
    public PlayingEntity player2;
    public boolean gameOver = false;
    public PlayingEntity player1;
    // 0-人机对战, 1-双人对战, 2-AI自对弈
    public int gameMode = 0;
    public int player1Type = 0; // 0-人类, 1-AI
    public int player2Type = 1; // 0-人类, 1-AI
    private boolean game = true;
    private static AlphaBetaAI ai;
    //250913完成标签栏设计
    Main(int gridSize, boolean swap) {
        String[] modeOptions = {"人机对战", "双人对战", "AI自对弈"};
        int modeSelect = JOptionPane.showOptionDialog(null,
                "请选择模式", "弈衡 - 六贯棋",
                JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
                null, modeOptions, "人机对战");

        if (modeSelect == 0) {
            gameMode = 0;
            int select = JOptionPane.showOptionDialog(null,
                    "选择本机先后手", "六贯棋",
                    JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
                    null, new String[]{"红方先手", "蓝方后手"}, "蓝方后手");

            if (0 == select) {
                player1Type = 0;
                player2Type = 1;
            } else {
                player1Type = 1;
                player2Type = 0;
            }
        } else if (modeSelect == 1) {
            gameMode = 1;
            player1Type = 0;
            player2Type = 0;
        } else if (modeSelect == 2) {
            gameMode = 2;
            player1Type = 1;
            player2Type = 1;
        }

        this.gridSize = gridSize;
        gamePiece = new AnyShapeButton[gridSize][gridSize];
        for (int i = 0; i < gridSize; i++) {
            for (int j = 0; j < gridSize; j++) {
                gamePiece[i][j] = new AnyShapeButton();
                gamePiece[i][j].x1 = i;
                gamePiece[i][j].y1 = j;
                gamePiece[i][j].addActionListener(new MouseAction(i, j, this));
            }
        }
        this.swap = swap;
        moveNumber = 1;
        moveList = new MoveList();
        currentPlayer = 1;
        game = true;
        gameOver = false;
        this.setTitle("弈衡 - 六贯棋 - " +
                (gameMode == 0 ? "人机对弈" :
                        gameMode == 1 ? "双人对弈" : "AI自对弈"));
        panel = new JPanel();
        panel.setLayout(null);

        for (int i = 0; i < gridSize; i++) {
            for (int j = 0; j < gridSize; j++) {
                gamePiece[i][j].setBounds(50 + 38 * j + 19 * i, 50 + 34 * i, 34, 40);
                panel.add(gamePiece[i][j]);
            }
        }

        JLabel[] topLabels = new JLabel[gridSize];
        JLabel[] bottomLabels = new JLabel[gridSize];
        JLabel[] leftLabels = new JLabel[gridSize];
        JLabel[] rightLabels = new JLabel[gridSize];

        String[] letters = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K","L","M","N","O","P","Q","R","S","T","U","V","X","Y","Z"};

        for (int i = 0; i < gridSize; i++) {
            topLabels[i] = new JLabel(letters[i]);
            topLabels[i].setForeground(Color.RED);
            topLabels[i].setBounds(  38 * i + 55, 20, 25, 40);//还是
            topLabels[i].setHorizontalAlignment(SwingConstants.CENTER);
            panel.add(topLabels[i]);
        }

        for (int i = 0; i < gridSize; i++) {
            bottomLabels[i] = new JLabel(letters[i]);
            bottomLabels[i].setForeground(Color.RED);
            bottomLabels[i].setBounds(40 + 38 * i + 19 * (gridSize), 40 + 34 * gridSize + 10, 34, 40);
            bottomLabels[i].setHorizontalAlignment(SwingConstants.CENTER);
            panel.add(bottomLabels[i]);
        }

        for (int i = 0; i < gridSize; i++) {
            leftLabels[i] = new JLabel(String.valueOf(i + 1));
            leftLabels[i].setForeground(Color.BLUE);
            leftLabels[i].setBounds(15, 50 + 34 * i, 30, 40);
            leftLabels[i].setHorizontalAlignment(SwingConstants.CENTER);
            panel.add(leftLabels[i]);
        }

        for (int i = 0; i < gridSize; i++) {
            rightLabels[i] = new JLabel(String.valueOf(i + 1));
            rightLabels[i].setForeground(Color.BLUE);
            rightLabels[i].setBounds(50 + 38 * gridSize + 19 * gridSize + 5, 50 + 34 * i, 30, 30);
            rightLabels[i].setHorizontalAlignment(SwingConstants.CENTER);
            panel.add(rightLabels[i]);
        }

        JPanel redLeftBoundary = new JPanel();
        redLeftBoundary.setBackground(new Color(200, 200, 255));
        redLeftBoundary.setBounds(0, 50, 15, 34 * gridSize);
        panel.add(redLeftBoundary);

        JPanel redRightBoundary = new JPanel();
        redRightBoundary.setBackground(new Color(200, 200, 255));
        redRightBoundary.setBounds(50 + 38 * gridSize + 19 * gridSize + 5 + 30, 50, 15, 34 * gridSize);
        panel.add(redRightBoundary);

        JPanel blueTopBoundary = new JPanel();
        blueTopBoundary.setBackground(new Color(255, 200, 200));
        blueTopBoundary.setBounds(50, 0, 38 * gridSize + 19 * gridSize, 15);
        panel.add(blueTopBoundary);

        JPanel blueBottomBoundary = new JPanel();
        blueBottomBoundary.setBackground(new Color(255, 200, 200));
        blueBottomBoundary.setBounds(50, 50 + 34 * gridSize + 10 + 40, 38 * gridSize + 19 * gridSize, 12);
        panel.add(blueBottomBoundary);

        JMenuBar jMenuBar = new JMenuBar();
        JMenu gameMenu = new JMenu("游戏");

        /*
        JMenuItem humanVsAI = new JMenuItem("人机对弈");
        humanVsAI.addActionListener(e -> changeGameMode(0));

        JMenuItem humanVsHuman = new JMenuItem("双人对弈");
        humanVsHuman.addActionListener(e -> changeGameMode(1));

        JMenuItem aiVsAI = new JMenuItem("AI自对弈");
        aiVsAI.addActionListener(e -> changeGameMode(2));
        */
        JMenuItem restart = new JMenuItem("重新开始");
        restart.addActionListener(e -> restartGame());
        /*
        gameMenu.add(humanVsAI);
        gameMenu.add(humanVsHuman);
        gameMenu.add(aiVsAI);
        */
        gameMenu.addSeparator();
        gameMenu.add(restart);

        jMenuBar.add(gameMenu);
        JMenu helpMenu = new JMenu("帮助");
        JMenuItem instructionsItem = new JMenuItem("说明");
        instructionsItem.addActionListener(e -> showInstructions());
        helpMenu.add(instructionsItem);
        jMenuBar.add(helpMenu);
        // 棋谱菜单
        JMenu recordMenu = new JMenu("棋谱");
        JMenuItem exportRecord = new JMenuItem("导出棋谱");
        exportRecord.addActionListener(e -> {
            if (ai != null) {
                ai.record.writeToFile();
                JOptionPane.showMessageDialog(null, "导出成功");
            } else {
                JOptionPane.showMessageDialog(null, "暂不支持导出双人对局");//我怎么想到把导出写到AI里边去的？
            }
        });
        recordMenu.add(exportRecord);
        jMenuBar.add(recordMenu);
        //251003修改了硬编码的问题，可自定义棋盘大小
        JMenu settingMenu = new JMenu("设置");
        JMenuItem boardSizeItem = new JMenuItem("棋盘大小设置");
        boardSizeItem.addActionListener(e -> {
            String input = JOptionPane.showInputDialog(this, "请输入棋盘大小（6-25）：", gridSize);
            if (input != null) {
                try {
                    int newSize = Integer.parseInt(input.trim());
                    if (newSize >= 6 && newSize <= 26) {
                        this.game = false;
                        Main newGame = new Main(newSize, true);
                        setPlayer1(newGame);
                        setPlayer2(newGame);
                        newGame.setVisible(true);
                        new Thread(newGame::run).start();
                        this.dispose();
                    } else {
                        JOptionPane.showMessageDialog(this, "棋盘大小范围6-25！");
                    }
                } catch (NumberFormatException ex) {
                    JOptionPane.showMessageDialog(this, "输入无效，请输入整数！");
                }
            }
        });
        settingMenu.add(boardSizeItem);
        jMenuBar.add(settingMenu);

        this.setJMenuBar(jMenuBar);
        //
        JLabel bgLabel = new JLabel();
        ImageIcon bgIcon = new ImageIcon("d.png");
        bgLabel.setIcon(bgIcon);
        bgLabel.setBounds(55*gridSize, 100, bgIcon.getIconWidth(), bgIcon.getIconHeight());
        /*
        //JButton b1 = new JButton("悔棋");
        b1.setBounds(600, 20, 70, 40);
        panel.add(b1);

        //JButton b2 = new JButton("棋谱");
        b2.setBounds(680, 20, 70, 40);
        b2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (ai != null) {
                    ai.record.writeToFile();
                    JOptionPane.showMessageDialog(null, "导出成功");
                } else {
                    JOptionPane.showMessageDialog(null, "无棋谱可导出");
                }
            }
        });

        panel.add(b2);
        */
        panel.add(bgLabel);
        this.add(panel);

        this.setSize(100 + 38 * gridSize + 19 * gridSize + 50, 150 + 34 * gridSize + 70);
        this.setVisible(true);
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
    }

    private void changeGameMode(int mode) {
        gameMode = mode;
        if (mode == 0) {
            int select = JOptionPane.showOptionDialog(null,
                    "请选择本机先后手", "六贯棋",
                    JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
                    null, new String[]{"红方先手", "蓝方后手"}, "蓝方后手");

            if (0 == select) {
                player1Type = 0;
                player2Type = 1;
            } else {
                player1Type = 1;
                player2Type = 0;
            }
        } else if (mode == 1) {
            player1Type = 0;
            player2Type = 0;
        } else if (mode == 2) {
            player1Type = 1;
            player2Type = 1;
        }

        restartGame();
    }


    private void restartGame() {
        this.game = false;
        Main newGame = new Main(gridSize, true);
        setPlayer1(newGame);
        setPlayer2(newGame);
        newGame.setVisible(true);

        new Thread(newGame::run).start(); // 在新线程中运行游戏循环，避免阻塞EDT
        this.dispose();
    }

    private void showInstructions() {
        //250912增添帮助选项
        String instructions =
                "联系作者：18613772039@163.com\n\n" +
                "六贯棋游戏规则说明:\n\n" +
                "1. 游戏目标:\n" +
                "   - 红方(先手): 在棋盘上形成上到下的连续路径\n" +
                "   - 蓝方(后手): 在棋盘上形成左到右的连续路径\n\n" +
                "2. 游戏规则:\n" +
                "   - 双方轮流在六边形格子上放置棋子\n" +
                "   - 先完成自己颜色路径连接的玩家获胜\n\n" +
                "3. 操作说明:\n" +
                "   - 点击空位放置棋子\n" +
                "   - 菜单中可以重新开始游戏、导出棋谱\n\n" +
                        "   - 棋谱位置为C:\\Users\\Admin\\Documents\\hexgame\n\n" +
                        "   - 在设置中可以修改棋盘大小，默认为11*11\n\n" +
                "4. 游戏模式:\n" +
                "   - 人机对战\n" +
                "   - 双人对战\n" +
                "   - AI自对弈";

        JTextArea textArea = new JTextArea(instructions);
        textArea.setEditable(false);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        textArea.setMargin(new Insets(10, 10, 10, 10));

        JScrollPane scrollPane = new JScrollPane(textArea);
        scrollPane.setPreferredSize(new Dimension(400, 300));

        JOptionPane.showMessageDialog(this, scrollPane, "游戏说明", JOptionPane.INFORMATION_MESSAGE);
    }

    public static void setPlayer1(Main game) {
        if (game.player1Type == 0) {
            game.player1 = new PlayerObject(1, game);
        } else {
            ai = new AlphaBetaAI(1, game);
            game.player1 = ai;
        }
    }

    public static void setPlayer2(Main game) {
        if (game.player2Type == 0) {
            game.player2 = new PlayerObject(2, game);
        } else {
            ai = new AlphaBetaAI(2, game);
            game.player2 = ai;
        }
    }

    public static void main(String[] args) {
        Main hex_ui = new Main(DEFAULT_SIDE, true);
        setPlayer1(hex_ui);
        setPlayer2(hex_ui);
        hex_ui.run();
    }

    public void run() {
        // 确保游戏状态重置
        //250912增添安全线程检查
        moveNumber = 1;
        moveList = new MoveList();
        currentPlayer = 1;
        gameOver = false;

        // 重置所有棋子状态
        for (int i = 0; i < gridSize; i++) {
            for (int j = 0; j < gridSize; j++) {
                gamePiece[i][j].setIcon(null);
                gamePiece[i][j].setBackground(null);
            }
        }


        while (game) {
            if (!checkForWinner()) {
                PlayingEntity player = GameAction.getPlayer(currentPlayer, this);
                if (player != null) {
                    player.getPlayerTurn();
                } else {
                    System.out.println("玩家为空");
                    break;
                }
            }
            currentPlayer = (currentPlayer % 2) + 1;

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("游戏线程结束");
    }

    private boolean checkForWinner() {
        GameAction.checkedFlagReset(this);
        if (GameAction.checkWinPlayer(1, this)) {
            game = false;
            gameOver = true;
            player1.win();
            player2.lose();
        } else if (GameAction.checkWinPlayer(2, this)) {
            game = false;
            gameOver = true;
            player1.lose();
            player2.win();
        }
        return gameOver;
    }
}

